package com.paypalpay.controller.pay;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.paypalpay.entity.common.UserboundPaymentOrder;
import com.paypalpay.entity.pay.WXNotificationpaymentResults;
import com.paypalpay.service.UserboundPaymentOrderService;
import com.paypalpay.service.WeixinNotificationpaymentService;
import com.paypalpay.util.pay.WxPayUtil;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class WeixinPayController {
    private static Logger logger = Logger.getLogger(WeixinPayController.class);

    @Autowired
    private HttpSession session;
    @Autowired
    WeixinNotificationpaymentService weixinNotificationpaymentService;

    @Autowired
    UserboundPaymentOrderService userboundPaymentOrderService;

    //微信支付的货币肯定是CNY人民币
    private String currency_code = "CNY";
    //微信公众号支付Type为1
    private String payType = "1";

    @CrossOrigin
    @ResponseBody
    @RequestMapping(value = "/weixinpay", method = RequestMethod.GET)
    public String paypay(HttpServletRequest request, HttpServletResponse res) {

        System.out.println("weixin支付请求的链接是：" + request.getRequestURL() + "?" + request.getQueryString());

        String deviceId = request.getParameter("deviceId");
        String deviceType = request.getParameter("deviceType");
        String orderId = request.getParameter("orderId");
        String temOrderId = request.getParameter("temOrderId");
        String openId = request.getParameter("openId");
        String partnerCode = request.getParameter("partnerCode");
        String packageCode = request.getParameter("packageCode");
        String orderPeriod = request.getParameter("orderPeriod");
        String orderUnit = request.getParameter("orderUnit");
        String amount = request.getParameter("amount");
        String paymentOrderId = request.getParameter("paymentOrderId");
        String isOpen = request.getParameter("isOpen");

        System.out.println("paymentOrderId是什么多少：" + paymentOrderId);
        System.out.println("orderId是什么多少：" + orderId);
        System.out.println("temOrderId到底是什么鬼：" + temOrderId);
        System.out.println("orderPeriod是什么多少：" + orderPeriod);
        System.out.println("amount是什么多少：" + amount);

        // 根据packageCode去查询一下当前用户购买的套餐名称，并且插入到数据库
        String packageName = "";
        System.out.println("packageCode是什么多少：" + packageCode);
        if (packageCode.contains(",") == true) {
            // 此情况说明packageCode有多个套餐
            String[] str = packageCode.split(",");
            for (int i = 0; i < str.length; i++) {
                String packages = str[i];
                packageName += userboundPaymentOrderService.getPackageNameByPackageCode(packages, partnerCode) + ",";
                System.out.println("取到的套餐名称：" + packageName);
            }
        } else {
            packageName = userboundPaymentOrderService.getPackageNameByPackageCode(packageCode, partnerCode);
            System.out.println("取到的套餐名称：" + packageName);
        }
        // 判断一下：openId和orderId同时存在时是有卡用户，没有orderId的是无卡用户
        if (!orderId.equals("") && !"undefined".equals(orderId)) {
            // 说明上来的有orderId
            if (!temOrderId.equals("") && !"undefined".equals(temOrderId)) {
                // 还上来了temOrderId，此时是要强行走无卡流程
                // 有orderId，有temOrderId，有openid，只要有temOrderId，肯定不会是非微信用户访问的
                System.out.println("orderId不为空，temOrderId也不为空，openid也不为空，强行走无卡流程！");
                UserboundPaymentOrder paymentOrder = new UserboundPaymentOrder();
                paymentOrder.setPartnerCode(partnerCode);
                paymentOrder.setPackageCode(packageCode);
                paymentOrder.setPackageName(packageName);
                paymentOrder.setPaymentOrderId(paymentOrderId);
                paymentOrder.setOpenId(openId);
                paymentOrder.setAmount(amount);
                paymentOrder.setOrderPeriod(orderPeriod);
                paymentOrder.setOrderUnit(orderUnit);
                paymentOrder.setIsOpen(isOpen);
                paymentOrder.setPayType(payType);
                paymentOrder.setOrderCurrency(currency_code);
                paymentOrder.setTemOrderId(temOrderId);
                // 根据收到的openId去更新数据表，此时iccid为null
                userboundPaymentOrderService.updateUserboundPaymentOrderNoCard(paymentOrder);

            } else {
                if (!openId.equals("")) {
                    //就是openid不为空的时候就是微信用户访问
                    // 有卡orderId不为空，temOrderId为空
                    System.out.println("orderId不为空，temOrderId为空，标准有卡流程！");
                    UserboundPaymentOrder paymentOrder = new UserboundPaymentOrder();
                    paymentOrder.setPartnerCode(partnerCode);
                    paymentOrder.setPackageCode(packageCode);
                    paymentOrder.setPackageName(packageName);
                    paymentOrder.setPaymentOrderId(paymentOrderId);
                    paymentOrder.setOrderId(orderId);
                    paymentOrder.setOpenId(openId);
                    paymentOrder.setAmount(amount);
                    paymentOrder.setOrderPeriod(orderPeriod);
                    paymentOrder.setOrderUnit(orderUnit);
                    paymentOrder.setIsOpen(isOpen);
                    paymentOrder.setPayType(payType);
                    paymentOrder.setOrderCurrency(currency_code);
                    paymentOrder.setDeviceId(deviceId);
                    // 根据收到的openId去更新数据表，iccid此时是有的，所以不能为null
                    userboundPaymentOrderService.updateUserboundWeixinPaymentOrder(paymentOrder);
                } else {
                    //非微信用户访问
                    // 有卡orderId不为空，temOrderId为空，openid为空
                    System.out.println("orderId不为空，temOrderId为空，标准有卡流程！");
                    UserboundPaymentOrder paymentOrder = new UserboundPaymentOrder();
                    paymentOrder.setPartnerCode(partnerCode);
                    paymentOrder.setPackageCode(packageCode);
                    paymentOrder.setPackageName(packageName);
                    paymentOrder.setPaymentOrderId(paymentOrderId);
                    paymentOrder.setOrderId(orderId);
                    paymentOrder.setDeviceId(deviceId);
                    paymentOrder.setAmount(amount);
                    paymentOrder.setOrderPeriod(orderPeriod);
                    paymentOrder.setOrderUnit(orderUnit);
                    paymentOrder.setIsOpen(isOpen);
                    paymentOrder.setPayType(payType);
                    paymentOrder.setOrderCurrency(currency_code);
                    // 根据收到的deviceId去更新数据表，deviceId此时是有的，所以不能为null,openid为空
                    userboundPaymentOrderService.updateUserboundNotWeixinPaymentOrder(paymentOrder);
                }
            }

        } else {
            // 无卡，没有orderId，deviceId为空，temOrderId不为空
            if (!temOrderId.equals("") && !"undefined".equals(temOrderId)) {
                System.out.println("orderId为空，temOrderId不为空，标准无卡流程！");
                UserboundPaymentOrder paymentOrder = new UserboundPaymentOrder();
                paymentOrder.setPartnerCode(partnerCode);
                paymentOrder.setPackageCode(packageCode);
                paymentOrder.setPackageName(packageName);
                paymentOrder.setPaymentOrderId(paymentOrderId);
                paymentOrder.setOpenId(openId);
                paymentOrder.setAmount(amount);
                paymentOrder.setOrderPeriod(orderPeriod);
                paymentOrder.setOrderUnit(orderUnit);
                paymentOrder.setIsOpen(isOpen);
                paymentOrder.setPayType(payType);
                paymentOrder.setTemOrderId(temOrderId);
                paymentOrder.setOrderCurrency(currency_code);
                // 根据收到的openId去更新数据表，此时deviceId为null
                userboundPaymentOrderService.updateUserboundPaymentOrderNoCard(paymentOrder);
            }
        }

        // 统一下单，返回xml，用return_code判断统一下单结果,获取prepay_id等预支付成功信息
        String jsonString = "";// 返回的json字串儿
        try {
            // 获取ip地址:
            String ipAddrStr = WxPayUtil.getIpAddr(request);
            // 将传过来的金额处理一下
            boolean flag = WeixinPayController.isInteger(amount);
            // 如果是整型
            if (flag == true) {
                try {
                    int Amount = Integer.valueOf(amount).intValue();
                    int totel_fee = Amount * 100;
                    String prePayInfoXml = WxPayUtil.unifiedOrder("TrafficCardPayment", paymentOrderId, totel_fee, ipAddrStr, openId);
                    logger.info("Controller中的prePayInfoXml：" + prePayInfoXml);
                    // 生成包含prepay_id的map，map传入前端
                    Map<String, Object> map = new HashMap<String, Object>();
                    map = WxPayUtil.getPayMap(prePayInfoXml);
                    // System.out.println("Controller中的map：" + map);
                    logger.info("Controller中的map：" + map);
                    // 将订单号放入map，用以支付后处理
                    map.put("orderNo", paymentOrderId);
                    // 将map中的数据取出来并且放在request域中去，传到页面上
                    String appId = (String) map.get("appId");
                    request.setAttribute("appId", appId);
                    String timeStamp = (String) map.get("timeStamp");
                    request.setAttribute("timeStamp", timeStamp);

                    String prepay_id = (String) map.get("prepay_id");
                    request.setAttribute("prepay_id", prepay_id);

                    String packageStr = (String) map.get("packageStr");
                    request.setAttribute("packageStr", packageStr);

                    String nonceStr = (String) map.get("nonceStr");
                    request.setAttribute("nonceStr", nonceStr);

                    String paySign = (String) map.get("paySign");
                    request.setAttribute("paySign", paySign);

                    HashMap map1 = new HashMap();
                    map1.put("appId", appId);
                    map1.put("prepay_id", prepay_id);
                    map1.put("timeStamp", timeStamp);
                    map1.put("nonceStr", nonceStr);
                    map1.put("package", "prepay_id=" + prepay_id);
                    map1.put("signType", "MD5");
                    map1.put("paySign", paySign);

                    JSONObject jsonObject = JSONObject.fromObject(map1);
                    System.out.println("输出的结果是：" + jsonObject);
                    // 3、将json对象转化为json字符串
                    jsonString = jsonObject.toString();
                    System.out.println(jsonString);
                    return jsonString;

                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }

            } else {
                try {
                    // DecimalFormat("#")表示float类型格式化时不要小数点了
                    DecimalFormat decimalFormat = new DecimalFormat("#");
                    float Amount = Float.parseFloat(amount);
                    int totel_fee = Integer.parseInt(decimalFormat.format(Amount * 100));
                    String prePayInfoXml = WxPayUtil.unifiedOrder("TrafficCardPayment", paymentOrderId, totel_fee, ipAddrStr, openId);
                    logger.info("Controller中的prePayInfoXml：" + prePayInfoXml);
                    // 生成包含prepay_id的map，map传入前端
                    Map<String, Object> map = new HashMap<String, Object>();
                    map = WxPayUtil.getPayMap(prePayInfoXml);
                    // System.out.println("Controller中的map：" + map);
                    logger.info("Controller中的map：" + map);
                    // 将订单号放入map，用以支付后处理
                    map.put("orderNo", orderId);
                    // 将map中的数据取出来并且放在request域中去，传到页面上
                    String appId = (String) map.get("appId");
                    request.setAttribute("appId", appId);
                    String timeStamp = (String) map.get("timeStamp");
                    request.setAttribute("timeStamp", timeStamp);

                    String prepay_id = (String) map.get("prepay_id");
                    request.setAttribute("prepay_id", prepay_id);

                    String packageStr = (String) map.get("packageStr");
                    request.setAttribute("packageStr", packageStr);

                    String nonceStr = (String) map.get("nonceStr");
                    request.setAttribute("nonceStr", nonceStr);

                    String paySign = (String) map.get("paySign");
                    request.setAttribute("paySign", paySign);

                    HashMap map1 = new HashMap();
                    map1.put("appId", appId);
                    map1.put("prepay_id", prepay_id);
                    map1.put("timeStamp", timeStamp);
                    map1.put("nonceStr", nonceStr);
                    map1.put("package", "prepay_id=" + prepay_id);
                    map1.put("signType", "MD5");
                    map1.put("paySign", paySign);

                    JSONObject jsonObject = JSONObject.fromObject(map1);
                    System.out.println("输出的结果是：" + jsonObject);
                    // 3、将json对象转化为json字符串
                    jsonString = jsonObject.toString();
                    System.out.println(jsonString);
                    return jsonString;

                } catch (Exception e) {
                    // TODO: handle exceptions
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return jsonString;
    }

    /**
     * 微信支付结果回调
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/wxNotify")
    @CrossOrigin
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        String deviceId = (String) session.getAttribute("deviceId");
        String deviceType = (String) session.getAttribute("deviceType");
        try {
            logger.info("微信支付回调获取数据开始");
            Map rMap = WxPayUtil.getNotifyResult(request);

            logger.info("微信支付回调notify获取的数据：" + rMap.get("resXml") + "");
            // 向微信输出处理结果，如果成功（SUCCESS），微信就不会继续调用了，否则微信会连续调用8次
            // 告诉微信服务器，我收到信息了，不要在通知我了
            response.getWriter().write(rMap.get("resXml") + "");

            logger.info("开始分析微信回调数据:");

            String paymentId = rMap.get("out_trade_no") + "";
            logger.info("微信回调数据:" + paymentId);
            String result_code = rMap.get("result_code") + "";
            String return_code = rMap.get("return_code") + "";

            String total_fee = rMap.get("total_fee") + "";
            int fee = Integer.parseInt(total_fee) / 100;
            String payAmount = Integer.toString(fee);

            String appid = rMap.get("appid") + "";

            String bank_type = rMap.get("bank_type") + "";
            String cash_fee = rMap.get("cash_fee") + "";
            String fee_type = rMap.get("fee_type") + "";
            String is_subscribe = rMap.get("is_subscribe") + "";

            String mch_id = rMap.get("mch_id") + "";
            String nonce_str = rMap.get("nonce_str") + "";
            String openid = rMap.get("openid") + "";
            String out_trade_no = rMap.get("out_trade_no") + "";

            String sign = rMap.get("sign") + "";
            String time_end = rMap.get("time_end") + "";
            String trade_type = rMap.get("trade_type") + "";
            String transaction_id = rMap.get("transaction_id") + "";

            //将微信回传的交易记录入库保存下来

            int c = userboundPaymentOrderService.findCountByOrderId(out_trade_no);
            if (c <= 0) {
                WXNotificationpaymentResults results = new WXNotificationpaymentResults();
                results.setAppid(appid);
                results.setBankType(bank_type);
                results.setCashFee(cash_fee);
                results.setFeeType(fee_type);
                results.setIsSubscribe(is_subscribe);
                results.setMchId(mch_id);
                results.setNonceStr(nonce_str);
                results.setOpenid(openid);
                results.setOutTradeNo(out_trade_no);
                results.setResultCode(result_code);
                results.setReturnCode(return_code);
                results.setSign(sign);
                results.setTimeEnd(time_end);
                results.setTotalFee(total_fee);
                results.setTradeType(trade_type);
                results.setTransactionId(transaction_id);
                results.setDeviceId(deviceId);
                results.setDeviceType(deviceType);

                weixinNotificationpaymentService.insertPaymentResults(results);
            }

            // 判断result_code和return_code同时是SUCCESS就return给北京
            if (result_code.equalsIgnoreCase("SUCCESS") || return_code.equalsIgnoreCase("SUCCESS")) {
                // 查询一下当前out_trade_no单号有没有通知过北京，要是通知过IsNotify肯定是0了，
                //根据微信回调的订单号去数据库查询当前记录是不是已经记录
                int count = userboundPaymentOrderService.findOrderIdByNotify(out_trade_no);
                if (count > 0) {
                    // 当前单号已经通知过了就不要再通知北京了
                    System.out.println("当前数据库已经有接收到微信回调并且已经入库");
                } else {
                    //根据微信回调的数据入库是否成功支付，根据paymentId这个id去数据插入支付结果
                    UserboundPaymentOrder paymentOrder = new UserboundPaymentOrder();
                    // 成功就将PayRst设为1；不插入就数据库默认0
                    paymentOrder.setPayRst("success");
                    // 成功就要通知，数据库就记1，不成功就不通知数据库会默认0
                    paymentOrder.setIsNotify("1");
                    paymentOrder.setPaymentOrderId(paymentId);
                    userboundPaymentOrderService.updatePayRst(paymentOrder);


                    // 去数据库查询一下out_trade_no这个单号对应的orderId
                    //String orderId = userboundPaymentOrderService.queryOrderIdByPaymentId(paymentId);
                    UserboundPaymentOrder userOrder = userboundPaymentOrderService.queryOrderByPaymentId(paymentId);
                    String partnerCode = userOrder.getPartnerCode();
                    String orderId = userOrder.getOrderId();
                    String DeviceId = userOrder.getDeviceId();
                    String DeviceType = userOrder.getDeviceType();
                    System.out.println("查询到的订单orderId是:" + orderId + ";DeviceId是:" + DeviceId + ";DeviceType是:" + DeviceType);

                    if (orderId != null && orderId.length() > 0) {
                        System.out.println("调用给北京回调支付通知的controller:");
                        //String orderId, String deviceId, String deviceType, String payType, String payAmount
                        return "forward:/payNotify?orderId=" + orderId + "&deviceId=" + DeviceId + "&deviceType=" + DeviceType + "&payType=" + payType + "&payAmount=" + payAmount + "" + "&partnerCode=" + partnerCode + "";
                    }

                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return null;
    }

    /*
     * 方法二：推荐，速度最快 判断是否为整数
     *
     * @param str 传入的字符串
     *
     * @return 是整数返回true,否则返回false
     * Pattern.compile("^[-\\+]?[\\d]*$")不要在方法体内直接实现
     */
    private static Pattern NUMBER_PATTERN = Pattern.compile("^[-\\+]?[\\d]*$");

    public static boolean isInteger(String str) {
        Pattern pattern = NUMBER_PATTERN;
        return pattern.matcher(str).matches();
    }

}
